using System;
using System.Collections.Generic;
using System.Text;
using Evolution.Engine.Interfaces;
using System.Collections;
using Evolution.Engine.Utilities;
using System.CodeDom.Compiler;

namespace Evolution.Engine.Managers
{
    public class ScriptManager : Singleton<ScriptManager>
    {
        private Hashtable _Code = new Hashtable();
        private Hashtable _Scripts = new Hashtable();

        public bool Exist(string asset)
        {
            return _Scripts.ContainsKey(asset);
        }

        public T Get<T>(string asset, string group)
        {
            if (!_Scripts.ContainsKey(asset))
            {
                T inter = Compile<T>(asset, group);
                _Scripts.Add(asset, inter);
            }

            return (T)_Scripts[asset];
        }

        private T Compile<T>(string asset, string group)
        {
            CompilerResults _Results = Utilities.CodeCompiler.Instance.CompileCode(asset, group);
            if (_Results.Errors.Count > 0)
                throw new CompileError(_Results.Errors, asset);

            _Code.Add(asset, _Results.CompiledAssembly);

            return (T)Utilities.CodeCompiler.Instance.FindInterface(
                _Results.CompiledAssembly,
                GetInterfaceName(typeof(T).ToString())
            );
        }

        private string GetInterfaceName(string interfacename)
        {
            string[] interfaceparts = interfacename.Split('.');
            return interfaceparts[interfaceparts.Length - 1];
        }
    }

    public class CompileError : Exception
    {
        private string myFile;
        private CompilerErrorCollection myErrors;

        public CompilerErrorCollection Errors { get { return myErrors; } set { myErrors = value; } }
        public string FileName { get { return myFile; } set { myFile = value; } }

        public CompileError(string file, string error)
            : base(error)
        {
            myFile = file;
        }

        public CompileError(CompilerErrorCollection errors, string file)
            : base("Errors in script")
        {
            myFile = file;
            myErrors = errors;
        }
    }
}
